
import Snake from './Snake';
import Food from "./Food";
import ScorePanel from "./ScorePanel";
// 游戏控制器
class GameControl{
    snake : Snake ;
    food : Food ;
    scorePanel : ScorePanel ;
    direction : string = '' ;
    isLive : boolean = true ;
    baseDelay = 300; // 初始延迟（等级1时）
    minDelay = 50;   // 最小延迟（速度上限）
    k = 0.12;        // 衰减系数（越大速度提升越快）
    constructor(){
        this.snake = new Snake();
        this.food = new Food();
        this.scorePanel = new ScorePanel(10,1) ;
        this.direction = '';
        this.init()
    }

    // 游戏初始化
    init() {
        document.addEventListener("keydown",this.keydownHandler.bind(this)) ;
        this.run() ;
    }
    keydownHandler(event : KeyboardEvent){
        // console.log(event);
        let new_direction = event.key;
        if (this.snake.bodies.length >= 2) {
            if (new_direction == "ArrowDown" && this.direction == "ArrowUp") {
                return
            }else if(new_direction == "ArrowUp" && this.direction == "ArrowDown"){
                return
            }else if (new_direction == "ArrowLeft" && this.direction == "ArrowRight"){
                return
            }else if (new_direction == "ArrowRight" && this.direction == "ArrowLeft"){
                return
            }
        }

        this.direction = new_direction;
    }

    run(){
        let x = this.snake.X ;
        let y = this.snake.Y ;
        let nx = this.snake.X ;
        let ny = this.snake.Y ;

        switch (this.direction) {
            case 'ArrowLeft':
                nx -= 10;
                break;
            case 'ArrowRight':
                nx += 10;
                break;
            case 'ArrowUp':
                ny -= 10;
                break;
            case 'ArrowDown' :
                ny += 10;
                break;
        }
        if(this.checkEat(nx,ny) ){
            this.food.change() ;
            this.scorePanel.addScore() ;
            this.snake.addBody() ;
            this.scorePanel.levelUp() ;
        }
        try{
            this.snake.moveBody() ;  // 有一瞬间蛇头位置和第二节身体重合
            this.snake.X =  nx ;  // 但紧接着蛇头位置更新
            this.snake.Y = ny ;
        }catch (e) {

            this.isLive = false;
        }

        this.isLive = !this.snake.checkSelfHit() ;
        if (!this.isLive) {
            alert("Game over") ;
        }

        // this.isLive && setTimeout(this.run.bind(this),  50 + (300 - this.scorePanel.level * 30) ) ;

        const delay = this.minDelay + (this.baseDelay - this.minDelay) * Math.exp(-this.k * this.scorePanel.level);
        const finalDelay = Math.max(Math.round(delay), this.minDelay);

        if (this.isLive) {
            setTimeout(this.run.bind(this), finalDelay);
        }
    }


    checkEat(X : number , Y : number){
        return X == this.food.X && Y == this.food.Y;
    }



}

export default GameControl;